#ifndef _MVDATA_MB_H_
#define _MVDATA_MB_H_

#include <list>
#include "MVDataMBCommon.h"
#include "MVDataBlock.h"

class CMVDataSubMB;

///@brief 封装一个Macro Block，对用户表现为内含1个或多个 CMVDataBlock 的容器，对库内部表示为 CMVDataSubMB 的容器。
class CMVDataMB : public CMVDataMBCommon
{
//============================== 一般方法 ====================================
public:
	CMVDataMB( TYPE_MB mbtype, int x = 0, int y = 0 );
	CMVDataMB();
	CMVDataMB( const CMVDataMB & mb );
	~CMVDataMB();

public:
	///@brief 比较两个Macro Block的坐标是否相同
	bool operator == ( const CMVDataMB& mbdata ) const;
	///@brief 比较两个Macro Block的坐标是否不同
	bool operator != ( const CMVDataMB& mbdata ) const;

	///@brief 复制内部的所有属性及逻辑对象
	CMVDataMB& operator = ( const CMVDataMB& mbdata );

//============================== 属性方法 ====================================
public:
	///@brief 设置MB的位置
	int SetCoordinate( int x, int y );
	///@brief 取出MB的位置，从参数返回
	int GetCoordinate( int& x, int& y ) const;
	///@brief 取出MB的位置，X
	int GetCoordinateX() const;
	///@brief 取出MB的位置，Y
	int GetCoordinateY() const;

	///@brief 取得MB类型
	TYPE_MB GetMBType() const;
	///@brief 设置MB类型
	int SetMBType( TYPE_MB type );

public:
	///@brief 向MB中增加一个block，如果加入的block与现有的Block重复则会更新现有block属性，如果加入的block与现有的block冲突，则返回错误
	int AddBlock( const CMVDataBlock * block );

	///@brief 删除指定位置上的Block
	int RemoveBlock( LOC_BLOCK first_layer_loc, LOC_BLOCK second_layer_loc );

	///@brief 迭代取得指定block的下一个block
	const CMVDataBlock * GetNextBlock( const CMVDataBlock * curr_block ) const;

	///@brief 取得指定位置的Block
	const CMVDataBlock * GetBlockByLoc ( LOC_BLOCK first_layer_loc, LOC_BLOCK second_layer_loc ) const;

	///@brief 取得内部的Block个数
	int GetBlockCount() const;

	///@brief 检查内部Block的完整性以及合法性
	bool CheckBlockValidation() const;

private:
	///@brief 当前MacroBlock是否含有SubMB
	bool HaveSubMB() const;
	///@brief 根据MB类型判断是否应当含有Sub MB
	bool ShouldHaveSubMB() const;

	///@brief 增加一个新的Sub Macro Block，无排序
	int AddSubMB( const CMVDataSubMB * submb );

	///@brief 取得指定位置的一个Sub Macro Block
	const CMVDataSubMB * GetSubMBByLocation( LOC_BLOCK mbloc ) const;

	///@brief 迭代访问所有的Sub Macro Block
	///@param curr_sub_mb 指向当前的SubMB指针，当 curr_mb==NULL 时返回第一个Sub Macro Block
	const CMVDataSubMB * GetNextSubMB( const CMVDataSubMB * curr_sub_mb ) const;

	///@brief 从 CMVDataBlock 类型对象中拷贝数据
	int CopyDataFromBlock( const CMVDataBlock * block );

	///@brief CMVDataMB::GetSubMBByLocation 的内部具体实现，仅供函数内部使用
	CMVDataSubMB * _GetSubMBByLocation( LOC_BLOCK mbloc ) const;

//============================== 类成员 ====================================
private:
	int m_ix;
	int m_iy;
	TYPE_MB m_eMBType;
	std::list<CMVDataSubMB*> * m_plstSubMB;

	friend class CMVDataAgent;
	friend class CMVDataAgentXML;

private:
	struct m_aBlockMap;
};

#endif // _MVDATA_MB_H_